using System;
using SD = System.Diagnostics;

namespace AzureContrib.WindowsAzure.Diagnostics
{
	/// <summary>
	/// Common base for <see cref="ITrace"/> and Helper.ITrace.
	/// </summary>
	public abstract class TraceBase : ITraceSwitchable, ITraceControls
	{
		internal readonly ITraceSwitchProvider traceSwitchProvider;
		/// <summary>
		/// ctor
		/// </summary>
		protected TraceBase(Type toLogFor, ITraceSwitchProvider traceSwitchProvider)
		{
			if (toLogFor == null) throw new ArgumentNullException("toLogFor");
			if (traceSwitchProvider == null) throw new ArgumentNullException("traceSwitchProvider");

			Switch = toLogFor.FullName;
			this.traceSwitchProvider = traceSwitchProvider;
		}

		/// <summary>
		/// ctor
		/// </summary>
		protected TraceBase(string @switch, ITraceSwitchProvider traceSwitchProvider)
		{
			if (@switch == null) throw new ArgumentNullException("@switch");
			if (string.IsNullOrWhiteSpace(@switch)) throw new ArgumentOutOfRangeException("@switch");
			if (traceSwitchProvider == null) throw new ArgumentNullException("traceSwitchProvider");

			Switch = @switch;
			this.traceSwitchProvider = traceSwitchProvider;
		}

		/// <summary>
		/// Gets the switch name of the current trace target
		/// </summary>
		public string Switch { get; private set; }

		/// <summary>
		/// Is tracing disabled for this <see cref="ITraceSwitchable.Switch"/>?
		/// </summary>
		/// <returns>True if tracing is disabled.</returns>
		public bool Disabled
		{
			get
			{
				return traceSwitchProvider.Disabled(this);
			}
		}

		/// <summary>
		/// Is tracing at the Verbose level enabled for this <see cref="ITraceSwitchable.Switch"/>?
		/// </summary>
		/// <returns>True if tracing is enabled.</returns>
		public bool VerboseEnabled
		{
			get
			{
				return traceSwitchProvider.VerboseEnabled(this);
			}
		}

		/// <summary>
		/// Is tracing at the Info level enabled for this <see cref="ITraceSwitchable.Switch"/>?
		/// </summary>
		/// <returns>True if tracing is enabled.</returns>
		public bool InformationEnabled
		{
			get
			{
				return traceSwitchProvider.InformationEnabled(this);
			}
		}

		/// <summary>
		/// Is tracing at the Warning level enabled for this <see cref="ITraceSwitchable.Switch"/>?
		/// </summary>
		/// <returns>True if tracing is enabled.</returns>
		public bool WarningEnabled
		{
			get
			{
				return traceSwitchProvider.WarningEnabled(this);
			}
		}

		/// <summary>
		/// Is tracing at the Error level enabled for this <see cref="ITraceSwitchable.Switch"/>?
		/// </summary>
		/// <returns>True if tracing is enabled.</returns>
		public bool ErrorEnabled
		{
			get
			{
				return traceSwitchProvider.ErrorEnabled(this);
			}
		}

		/// <summary>
		/// Simple formatting that prepends the Switch with a pipe to the message.
		/// </summary>
		protected string SwitchFormat(string category, string message)
		{
			return new TraceMessage(category, Switch, message);
		}

		/// <summary>
		/// Simple formatting that prepends the Switch with a pipe to the message.
		/// </summary>
		protected string SwitchFormat(SD.TraceLevel traceLevel, string message)
		{
			return SwitchFormat(traceLevel.ToString(), message);
		}
	}
}